package com.lanyou.esb.cook.proxy.service.impl;

import java.io.IOException;
import java.util.Date;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.lanyou.esb.cook.proxy.common.Constants;
import com.lanyou.esb.cook.proxy.common.SystemResCode;
import com.lanyou.esb.cook.proxy.dao.impl.BaseDao;
import com.lanyou.esb.cook.proxy.entity.IfAlarm;
import com.lanyou.esb.cook.proxy.entity.IfAlrReqTimes;
import com.lanyou.esb.cook.proxy.entity.IfReqQuantity;
import com.lanyou.esb.cook.proxy.exception.IfAlarmException;
import com.lanyou.esb.cook.proxy.meta.AlarmLevel;
import com.lanyou.esb.cook.proxy.meta.AlarmType;
import com.lanyou.esb.cook.proxy.redis.proxy.impl.IfReqQuantityJedisProxy;
import com.lanyou.esb.cook.proxy.service.IfReqQuantityService;

/**
 * 接口请求量控制服务
 * 
 * @author Davey.wu
 */
public class IfReqQuantityServiceImpl implements IfReqQuantityService {
	/** 数据库操作接口 **/
	private BaseDao<IfReqQuantity> dao;
	/** Redis代理接口 **/
	private IfReqQuantityJedisProxy jedisProxy;

	@Override
	public IfAlarm alarm(IfReqQuantity quantity, IfAlrReqTimes ifAlrReqTimes,
			Date requestTime) throws IfAlarmException {
		if (quantity == null) {
			// 为NULL无告警
			return null;
		}
		// 已达到最大访问次数，不能访问
		if (ifAlrReqTimes.getTimes() >= quantity.getReqMax()) {
			if (TraceLogServiceImpl.isTrace()) {
				// 记录跟踪日志
				TraceLogServiceImpl.addTraceLog(
						SystemResCode.MSG_OVER_MAX_ACC_LIMIT,
						Constants.FLAG_LEFT_SQUARE_BRACKET, Constants.REQ_MAX,
						Constants.FLAG_EQUAL, quantity.getReqMax() + "",
						Constants.FLAG_COMMA_SYMBOL, Constants.CUR_REQ_TIMES,
						Constants.FLAG_EQUAL, ifAlrReqTimes.getTimes() + "",
						Constants.FLAG_RIGHT_SQUARE_BRACKET);
			}
			throw new IfAlarmException(SystemResCode.MSG_OVER_MAX_ACC_LIMIT,
					SystemResCode.CODE_OVER_MAX_ACC_LIMIT,
					AlarmType.REQUEST_OVER_LIMIT, AlarmLevel.URGENT,
					ifAlrReqTimes.getTimes(), quantity.getReqThreshold());
		}
		// 达到阀值
		if (ifAlrReqTimes.getTimes() >= quantity.getReqThreshold()) {
			Date now = new Date();
			IfAlarm ifAlarm = new IfAlarm();
			ifAlarm.setAlarmType(AlarmType.REQUEST_OVER_LIMIT.ValueCode);
			ifAlarm.setAlarmLevel(AlarmLevel.GENERAL.ValueCode);
			ifAlarm.setFlow(ifAlrReqTimes.getTimes());
			ifAlarm.setFowThreshold(quantity.getReqThreshold());
			ifAlarm.setErrorDate(now);
			ifAlarm.setCreateDate(now);
			return ifAlarm;
		}
		return null;
	}

	@Override
	public void loadAllToRedis() {
		try {
			jedisProxy.loadHashAll(dao.findAll());
		} catch (JsonProcessingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@Override
	public IfReqQuantity get(String ifId, String reqUnit) {
		try {
			return jedisProxy.hget(jedisProxy.getKeyFromFields(ifId, reqUnit));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public void reload(IfReqQuantity quantity) {
		try {
			jedisProxy.reloadHash(quantity);
		} catch (JsonProcessingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public IfReqQuantityJedisProxy getJedisProxy() {
		return jedisProxy;
	}

	public void setJedisProxy(IfReqQuantityJedisProxy jedisProxy) {
		this.jedisProxy = jedisProxy;
	}

	public BaseDao<IfReqQuantity> getDao() {
		return dao;
	}

	public void setDao(BaseDao<IfReqQuantity> dao) {
		this.dao = dao;
	}

}
